-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add multipart request support #65
base: master
Are you sure you want to change the base?
Conversation
Here's an example of a CHANGELOG.md entry: * [#65](https://github.com/ashkan18/graphlient/pull/65): Add multipart request support - [@pucinsk](https://github.com/pucinsk). Generated by 🚫 Danger |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty cool, but it seems strange to me that you would have to use a different adapter to send a file. Shouldn't I be able to do that by default?
spec/graphlient/adapters/http/faraday_multipart_adapter/format_multipart_variables_spec.rb
Outdated
Show resolved
Hide resolved
@@ -17,4 +17,5 @@ Gem::Specification.new do |s| | |||
s.add_dependency 'faraday' | |||
s.add_dependency 'faraday_middleware' | |||
s.add_dependency 'graphql-client' | |||
s.add_dependency 'mime-types' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gems related to mime types are known to allocate excessive memory. Have you looked into the mini_mime gem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I haven't thought about it.
Yup, mini_mime
should work as expected too.
And what do you think if we try to load mime types lib from users environment and if he does not have any mime types library then we throw an expection and enforce user to install mime types lib with a message_No mime types library detected you must add to your Gemfile mime-types
or mini_mime
gem_?
Code could look something like that:
def mime_type(file)
if defined?(MIME::TYPES)
MIME::TYPES.type_for(file.path)
if defined?(MiniMyme)
MiniMyme.lookup_by_filename(file.path)
else
raise Graphlient::Errors::NoMimeTypesLibError, 'Please add `mime-types` or `mini_mime` gem to your Gemfile'
end
end
It would nice for Rails users because Rails already includes mime-types
gem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a good idea 👍
|
||
response.body | ||
rescue Faraday::ClientError => e | ||
raise Graphlient::Errors::FaradayServerError, e |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't seem right to translate client errors to server errors. Also, you don't have to pass in the e
to the second argument as Ruby captures the cause and users have access to it with exception#cause
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh, it was shamefully copy-pasted from FaradayAdapter
So I cannot tell why it does looks so.
let(:variables) { { val: { file: File.new('spec/support/fixtures/empty.txt') } } } | ||
|
||
it 'contverts file to Faraday::UploadIO' do | ||
expect(call[:val][:file]).to be_a(Faraday::UploadIO) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Ruby, duck typing is more preferable rather than checking classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding this and also adding specs! Looks awesome! 😍
Just have the same question as @dblock about possibly not needing a separate adapter for this and have Faraday middleware handling this. I wonder if its sufficient to just set proper header for multipart requests and have Faraday handle it automatically.
|
||
def file_variable_value(file) | ||
content_type = MIME::Types.type_for(file.path).first | ||
return Faraday::UploadIO.new(file.path, content_type) if content_type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we use Faraday::FilePart
or Faraday::ParamPart
based on this doc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mhm. Good point. Faraday::UploadIO
will be deprecated. 😞 But in Faraday v0.17.0
UploadIO
is only valid way to add files to request.
I think the next Faraday version will v1.0
and it will have Faraday::Parts
module where all parts of request will be described.
Maybe we should specify faraday
gem version in Gemfile just to make sure that for now Faraday::UploadIO
could work?
@pucinsk My biggest reservation about this PR is the creation of another adapter. Can we build multipart support into the existing one? What's the downside? |
There are no downsides. I thought that it could be optional adapter. |
Thanks @pucinsk, yes that would be awesome to add support to existing adapter. Thanks so much! |
Yes, 1 adapter > 2 adapters. |
Hi can you merge the branch? I would like to use this functionality |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please see above. From the user POV a separate adapter is too difficult to use, as it requires creating a separate client to upload files from other requests. The ask is to integrate support for multipart requests into the existing one. Happy to merge something along those lines.
Alright master. Can you help me with some file upload example that still manages to leverage the gem |
I've never done that myself, so don't know how to do it with the current implementation. If you want to try and refactor this PR to support multipart I can try to help out fix any remaining issues on something that (almost) works. |
Hello guys, is there any way to send files with Graphlient, or only with this PR? |
I don't know of one. |
This PR allows send files via graphql. It adds
FaradayMultipartAdapter
to allow send multipart requests via graphlient gem.It accepts
File
instances and convert its toFaraday::UploadIO
before sending.